/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.jack.utils;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

/**
 *
 * from http://gophinight.bokee.com/5422985.html
 * http://dev.10086.cn/cmdn/wiki/index.php?doc-view-1981
 */
public class ImageUtils2 {
    /*图像变换
     用法举例:
     1.将一张图片pic转换成176*208的图
     pic=transImage(pic,176,208);
     2.将一张图片pic转换成原来的两倍大
     pic=scaleImage(pic,2,1);
     3.将一张图片pic转换成原来的三分之二
     pic=scaleImage(pic,2,3);     
     */

    /**
     *
     * @param src 需要变换的图片 图片变换比例 scales1:scales2
     * @param scales1 新图片
     * @param scales2 旧图片
     * @return
     */
    public static Image scaleImageOffScreen(Image src, int scales1, int scales2) {
        return transImageOffScreen(src, src.getWidth() * scales1 / scales2, src
                .getHeight()
                * scales1 / scales2);
    }

    /**
     *
     * @param src 需要变换的图片
     * @param w 要变换的宽
     * @param h 要变化的高
     * @return
     */
    public static Image transImageOffScreen(Image src, int w, int h) {
        int srcW = src.getWidth();// 图片的宽度   
        int srcH = src.getHeight();// 图片的高度   
        int dstW = w, dstH = h;
        Image tmp = Image.createImage(dstW, srcH); // 申请个宽为dstW高为srcH的图片空间   
        Graphics g = tmp.getGraphics();
        int scale = 16;
        int delta = (srcW << scale) / dstW;// 扫描长度   
        int pos = delta / 2;// 扫描位置   
        for (int x = 0; x < dstW; x++) {
            g.setClip(x, 0, 1, srcH);
            g.drawImage(src, x - (pos >> scale), 0, Graphics.LEFT
                    | Graphics.TOP);
            pos += delta;
        }
        Image dst = Image.createImage(dstW, dstH);
        g = dst.getGraphics();
        delta = (srcH << scale) / dstH;
        pos = delta / 2;
        for (int y = 0; y < dstH; y++) {
            g.setClip(0, y, dstW, 1);
            g.drawImage(tmp, 0, y - (pos >> scale), Graphics.LEFT
                    | Graphics.TOP);
            pos += delta;
        }
        tmp = null;
        return dst;
    }

    public static Image ZoomImageRGB(Image src, int desW, int desH) {
        return ZoomImageRGB(src, desW, desH, true);
    }

    public static Image ZoomImageRGB(Image src, int desW, int desH, boolean processAlpha) {
        Image desImg = null;
        int srcW = src.getWidth(); // 原始图像宽
        int srcH = src.getHeight(); // 原始图像高
        int[] srcBuf = new int[srcW * srcH]; // 原始图片像素信息缓存

        src.getRGB(srcBuf, 0, srcW, 0, 0, srcW, srcH);

        // 计算插值表
        int[] tabY = new int[desH];
        int[] tabX = new int[desW];

        int sb = 0;
        int db = 0;
        int tems = 0;
        int temd = 0;
        int distance = srcH > desH ? srcH : desH;
        for (int i = 0; i <= distance; i++) {
            tabY[db] = sb;
            tems += srcH;
            temd += desH;
            if (tems > distance) {
                tems -= distance;
                sb++;
            }
            if (temd > distance) {
                temd -= distance;
                db++;
            }
        }

        sb = 0;
        db = 0;
        tems = 0;
        temd = 0;
        distance = srcW > desW ? srcW : desW;
        for (int i = 0; i <= distance; i++) {
            tabX[db] = (short) sb;
            tems += srcW;
            temd += desW;
            if (tems > distance) {
                tems -= distance;
                sb++;
            }
            if (temd > distance) {
                temd -= distance;
                db++;
            }
        }

        // 生成放大缩小后图形像素buf
        int[] desBuf = new int[desW * desH];
        int dx = 0;
        int dy = 0;
        int sy = 0;
        int oldy = -1;
        for (int i = 0; i < desH; i++) {
            if (oldy == tabY[i]) {
                System.arraycopy(desBuf, dy - desW, desBuf, dy, desW);
            } else {
                dx = 0;
                for (int j = 0; j < desW; j++) {
                    desBuf[dy + dx] = srcBuf[sy + tabX[j]];
                    dx++;
                }
                sy += (tabY[i] - oldy) * srcW;
            }
            oldy = tabY[i];
            dy += desW;
        }

        // 生成图片
        desImg = Image.createRGBImage(desBuf, desW, desH, processAlpha);
        return desImg;
    }

    public static Image scaleImageRGB(Image src, int destW, int destH) {
        return scaleImageRGB(src, destW, destH, true);
    }

    public static Image scaleImageRGB(Image src, int destW, int destH, boolean processAlpha) {
        Image result = null;
        try {
            int srcW = src.getWidth();
            int srcH = src.getHeight();

            int[] srcRGB = new int[srcW * srcH];
            src.getRGB(srcRGB, 0, srcW, 0, 0, srcW, srcH);

            int destRGB[] = new int[destW * destH];

            // calculations and bit shift operations to optimize the for loop
            int tempScaleRatioWidth = ((srcW << 16) / destW);
            int tempScaleRatioHeight = ((srcH << 16) / destH);

            int i = 0;

            for (int y = 0; y < destH; y++) {
                for (int x = 0; x < destW; x++) {
                    destRGB[i++] =
                            srcRGB[(srcW * ((y * tempScaleRatioHeight) >> 16))
                            + ((x * tempScaleRatioWidth) >> 16)];
                }
            }

            result = Image.createRGBImage(destRGB, destW, destH, processAlpha);
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
            System.out.println("Out of memory " + e.getMessage());
        }

        return result;
    }

    /*
     * J2ME 渐变色的处理方法 
     */
    private static int[] retrieveRGBComponent(int color) {
        int[] rgb = new int[3];
        rgb[0] = (color & 0x00ff0000) >> 16;
        rgb[1] = (color & 0x0000ff00) >> 8;
        rgb[2] = (color & 0x000000ff);
        return rgb;
    }

    private static int[] generateTransitionalColor(int color1, int color2,
            int steps) {
        int[] color1RGB = retrieveRGBComponent(color1);
        int[] color2RGB = retrieveRGBComponent(color2);
        if (steps < 3 || color1RGB == null || color2RGB == null) {
            return null;
        }
        int[] colors = new int[steps];
        colors[0] = color1;
        colors[colors.length - 1] = color2;
        steps = steps - 2;
        int redDiff = color2RGB[0] - color1RGB[0];
        int greenDiff = color2RGB[1] - color1RGB[1];
        int blueDiff = color2RGB[2] - color1RGB[2];
        // from the second to the last second.  
        for (int i = 1; i < colors.length - 1; i++) {
            colors[i] = generateFromRGBComponent(new int[]{
                        color1RGB[0] + redDiff * i / steps,
                        color1RGB[1] + greenDiff * i / steps,
                        color1RGB[2] + blueDiff * i / steps});
        }
        return colors;
    }

    private static int generateFromRGBComponent(int[] rgb) {
        if (rgb == null || rgb.length != 3 || rgb[0] < 0 || rgb[0] > 255
                || rgb[1] < 0 || rgb[1] > 255 || rgb[2] < 0 || rgb[2] > 255) {
            return 0xfffff;
        }
        return rgb[0] << 16 | rgb[1] << 8 | rgb[2];
    }

    /**
     *
     * @param g
     * @param x 起始X
     * @param y 起始Y
     * @param width 宽度
     * @param height 高度
     * @param TransStart 渐变开始颜色
     * @param TransEnd 渐变结束颜色
     * @param direction 渐变的方向， 0 从左到右 1 从上到下
     */
    public void drawSelectedBackground(Graphics g, int x, int y, int width,
            int height, int TransStart, int TransEnd, int direction) {
        int[] line;
        Image lineImg;
        switch (direction) {
            case 0:
                // 这样写是从左到右渐变  
                line = generateTransitionalColor(TransStart, TransEnd, width);
                lineImg = Image.createRGBImage(line, line.length, 1, false);
                for (int i = 0; i < height; i++) {
                    g.drawImage(lineImg, x, y + i, Graphics.LEFT | Graphics.TOP);
                }
                break;
            case 1:
                // 下面的写法是从上到下渐变  
                line = generateTransitionalColor(TransStart, TransEnd, height);
                lineImg = Image.createRGBImage(line, 1, line.length, false);
                for (int i = 0; i < width; i++) {
                    g.drawImage(lineImg, x + i, y, Graphics.LEFT | Graphics.TOP);
                }
                break;
        }



    }
}
